from gui.gui import *
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
from wowMouseKeyboard import *
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.interval import IntervalTrigger

from util.memoryUtil import *
from util.configUtil import *
from util.FileUtil import *
import logging
import logging.config

import win32api, win32gui, win32con
import os
import time
from enum import Enum
from pynput.keyboard import Controller as kController
import redis

import numpy as np
from PIL import ImageGrab, Image

logging.config.fileConfig("./util/logging.conf")
log = logging.getLogger("example")
fileFullPath = './wowCache.txt'
fileObj = FileUtil()


class mywindow(QtWidgets.QMainWindow, Ui_MainWindow):
    # 基于UI半透明界面的全局变量区
    # 当前正在运行的按键和鼠标(防止重复按键)
    RUNNING_KEY_POOL = []
    # 新引入的redis，用于控制进程，线程，间的控制
    # redis_pool = redis.ConnectionPool(host='127.0.0.1', port=6379, password='', db=0)
    # redis_conn = redis.Redis(connection_pool=redis_pool)
    stopLoop = False

    def __init__(self):
        super(mywindow, self).__init__()
        self.setupUi(self)
        self.setMouseTracking(True)

    # 不工作，后期再来调试
    def mouseMoveEvent(self, e):
        x = e.x()
        y = e.y()
        text = "x: {0},  y: {1}".format(x, y)
        # self.label.setText(text)
        print(text)
        self.setWindowTitle(text)


# 全局变量
global ui
global MainWindow
global schedulerInGame


#  自定义的槽函数
def tabfun(index):
    print("点击了第:" + "  " + str(index) + ",个标签页")
    if index == 0:
        # 停止游戏，切换到中文进行聊天
        change_lan(Lan.ZH)
        pauseListen(False)
        terminateAllThreadPool()
        freeThreadPool()
    elif index == 1:
        # 切换到英文，准备开始自动游戏
        change_lan(Lan.EN)
        pauseListen(False)
    elif index == 2:
        change_lan(Lan.EN)
        objPlayer = oo(ui.comboBox.currentText(), ui, MainWindow)

        # pauseListen(False)
    elif index == 3:
        change_lan(Lan.EN)
        pauseListen(False)
    return


def pushButtonStartlistener_click():
    # 继续监听/启动监听
    resumeListen(True)
    # 把当前选择的职业文本传递过去，这样才能实现python的多肽
    log.debug('当前选择的职业为:' + ui.comboBox.currentText())
    objPlayer = oo(ui.comboBox.currentText(), ui, MainWindow)
    # 全局定时执行的一个动作
    triggerInGame = IntervalTrigger(seconds=5)
    schedulerInGame.remove_all_jobs()
    schedulerInGame.add_job(objPlayer.schedulerAction, triggerInGame, id='yehaibo')
    # schedulerInGame.state
    if schedulerInGame.running != True:
        schedulerInGame.start()
    log.debug('**********************************************************************************************')
    # 测试ui能访问到的界面元素
    # ui.checkBox_SM_Jump2Wolf.isChecked()
    # 写文件，到下次重新启动程序的时候，可以直接从文件中读取上次选中的职业，这样不用每次慌张地去二次选择职业
    fileObj.writeFile(fileFullPath, ui.comboBox.currentText())
    # aa = fileObj.readFile(fileFullPath)
    return


def pushButtonStopListener_click():
    # 暂停监听/停止监听
    pauseListen(False)
    # 全局定时器自动执行停止
    schedulerInGame.pause_job(job_id='yehaibo')
    return


def pushButtonCatchVideo_click():
    # lineEdit_X
    # lineEdit_Y
    # lineEdit_width
    # lineEdit_height
    avg_color = 0
    im = ImageGrab.grab(
        bbox=(
            int(ui.lineEdit_X.text()), int(ui.lineEdit_Y.text()),
            int(ui.lineEdit_X.text()) + int(ui.lineEdit_width.text()),
            int(ui.lineEdit_Y.text()) + int(ui.lineEdit_height.text())))  # X1,Y1,X2,Y2
    im_numpy = np.array(im.getdata(), dtype='uint8').reshape((im.size[1], im.size[0], 3))
    im_pil = Image.fromarray(im_numpy)
    r, g, b = im_pil.split()  # 分离三通道
    if ui.comboBox_RGB.currentText() == 'r':
        r.thumbnail((1, 1))  # 图片缩放为一个像素点
        avg_color = r.getpixel((0, 0))
    elif ui.comboBox_RGB.currentText() == 'g':
        g.thumbnail((1, 1))  # 图片缩放为一个像素点
        avg_color = g.getpixel((0, 0))
    elif ui.comboBox_RGB.currentText() == 'b':
        b.thumbnail((1, 1))  # 图片缩放为一个像素点
        avg_color = b.getpixel((0, 0))

    ui.plainTextEdit_ShowResult.appendPlainText(str(avg_color))
    return


def pushButtonClearVideo_click():
    ui.plainTextEdit_ShowResult.clear()
    return


def pushButton_10v10():
    # 评级中不带自动选择队伍
    t10v10 = threading.Thread(target=pushButton_10v10_in_thread)
    t10v10.start()
    return


def pushButton_10v10_Full_SelectTeam():
    # 评级中带自动选择队伍，在夜间全自动运行和判断
    t10v10 = threading.Thread(target=pushButton_10v10_in_thread)
    t10v10.start()
    return


def pushButton_10v10_in_thread():
    player.sleep(2)
    player.stopLoop = False
    while player.stopLoop == False:

        for i in range(1, 4):
            # 取消复活(可能和职业选择的勾勾冲突，因此向前调整一小点)
            player.ExecutemouseMove(923, 183 + i * 4)
            player.ExecutemouseLeftClick()
            player.sleep(0.1)

        for i in range(1, 30):
            # 坦克、治疗的职业选择，和进入评级，两个一起确认(团本的确认也在一起了)
            player.ExecutemouseMove(929, 280 + i * 4)
            player.ExecutemouseLeftClick()
            player.sleep(0.1)

        for i in range(1, 8):
            # SKada+团长就位确认
            player.ExecutemouseMove(906, 564 + i * 4)
            player.ExecutemouseLeftClick()
            player.sleep(0.1)

        for i in range(1, 14):
            # 退出比赛
            player.ExecutemouseMove(951, 780 + i * 4)
            player.ExecutemouseLeftClick()
            player.sleep(0.1)
        player.click(player.kb, Key.space, 1)
        player.sleep(0.4)
    return


def pushButton_stop():
    player.stopLoop = True
    return


def organizeTab(ui):
    # 界面一打开，就会执行这里
    log.debug("UI界面启动执行的初始化，其中 startListen ，是永远不会第二次执行到这里的")
    startListen()  # 永远不会第二次执行到这里，因此不会触发异常，大的控制，全部在tab切换的事件那里去控制了
    pauseListen(False)  # 我们一开始实际就启动了监听，之后在界面初始化之初，就把他停止在这里了|主要就是通过这里的 False 来控制默认都不监听
    ui.tabWidget.setCurrentIndex(0)
    ui.tabWidget.currentChanged['int'].connect(tabfun)

    scheduler = BackgroundScheduler()
    trigger1 = IntervalTrigger(seconds=int(getIni("./util", "memory", "interval")))
    scheduler.add_job(freePythonMemory, trigger1)

    trigger2 = IntervalTrigger(seconds=int(getIni("./util", "threadPool", "interval")))
    scheduler.add_job(freeThreadPool, trigger2)
    scheduler.start()

    # 按键的事件绑定
    ui.pushButtonStartlistener.clicked.connect(pushButtonStartlistener_click)
    ui.pushButtonStopListener.clicked.connect(pushButtonStopListener_click)
    ui.pushButtonRestart.clicked.connect(restart)
    # 捕捉视频中的平均像素值
    ui.pushButtonCatchVideo.clicked.connect(pushButtonCatchVideo_click)
    ui.pushButtonClearVideo.clicked.connect(pushButtonClearVideo_click)

    # 排评级(不带自动选择队伍)
    ui.pushButton_10v10.clicked.connect(pushButton_10v10)
    # 评级带自动选择队伍
    ui.pushButton_10v10_Full_SelectTeam.clicked.connect(pushButton_10v10_Full_SelectTeam)

    ui.pushButton_stop.clicked.connect(pushButton_stop)

    ui.pushButtonReboot.clicked.connect(restart)

    # 在启动后，读取上次的wow文件

    if (os.path.exists(fileFullPath) == False):
        # 文件不存在，第一次的新创建
        fileObj.writeFile(fileFullPath, ui.comboBox.currentText())
    else:
        # 已经存在了，就需要读取，并且选择selectItewm
        playerFromPreviousFile = fileObj.readFile(fileFullPath)
        ui.comboBox.setCurrentText(playerFromPreviousFile)
    return


class Lan(Enum):
    """
    语言代码值参考：https://msdn.microsoft.com/en-us/library/cc233982.aspx
    """
    EN = 0x4090409
    ZH = 0x8040804


def change_lan(lan: Lan):
    """
    修改当前激活窗口输入法
    :param lan: 语言类型
    :return: True 修改成功，False 修改失败
    """
    # 获取系统输入法列表
    hwnd = win32gui.GetForegroundWindow()
    im_list = win32api.GetKeyboardLayoutList()
    im_list = list(map(hex, im_list))

    # 加载输入法
    if hex(lan.value) not in im_list:
        win32api.LoadKeyboardLayout('0000' + hex(lan.value)[-4:], 1)

    result = win32api.SendMessage(
        hwnd,
        win32con.WM_INPUTLANGCHANGEREQUEST,
        0,
        lan.value)
    if result == 0:
        log.debug('设置%s键盘成功！' % lan.name)
    return result == 0


def setMainWindowAttr(MainWindow):
    MainWindow.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)  # 这一句的作用，是把窗口始终在最前面显示。
    MainWindow.setWindowOpacity(0.2)  # 设置窗口透明度
    MainWindow.move(1590, 850)  # 调整窗口的x，y坐标位置
    # 显示鼠标的坐标
    # MainWindow.setWindowTitle('test1')

    return


def restart():
    # 执行之前，先要把停掉
    # ★★★★★★★★★★★★★★★★★★★★★★在 Player.py中搜索 batFilePath 关键字，可以搜索到通过windows建，触发程序终止的程序
    # pauseListen(False)
    # 避免批处理弹出黑框
    win32api.ShellExecute(0, 'open', getIni("../util", "bat", "batFilePath"), '', '', 0)
    return


if __name__ == '__main__':
    change_lan(Lan.EN)
    app = QApplication(sys.argv)
    MainWindow = QMainWindow()
    schedulerInGame = BackgroundScheduler()
    # 修改为全局变量
    ui = mywindow()
    ui.setupUi(MainWindow)

    # 设置窗口的一些属性
    setMainWindowAttr(MainWindow)
    MainWindow.show()
    organizeTab(ui)
    sys.exit(app.exec_())
